import * as React from 'react';
import * as ReactDOM from 'react-dom';
import Tree from '../components/Tree/Tree';
import { fromJS, List } from "immutable";

class App extends React.PureComponent<any, any> {

  private newCount = 1;
  constructor(props, context) {
    super(props, context);

    this.state = {
      nodes: fromJS([
        {
          value: '/app',
          label: 'app',
          children: [
            {
              value: '/app/Http',
              label: 'Http',
              children: [
                {
                  value: '/app/Http/Controllers',
                  label: 'Controllers',
                  children: [{
                    value: '/app/Http/Controllers/WelcomeController.js',
                    label: 'WelcomeController.js',
                  }],
                },
                {
                  value: '/app/Http/routes.js',
                  label: 'routes.js',
                },
              ],
            },
            {
              value: '/app/Providers',
              label: 'Providers',
              children: [{
                value: '/app/Http/Providers/EventServiceProvider.js',
                label: 'EventServiceProvider.js',
              }],
            },
          ],
        },
        {
          value: '/config',
          label: 'config',
          children: [
            {
              value: '/config/app.js',
              label: 'app.js',
            },
            {
              value: '/config/database.js',
              label: 'database.js',
            },
          ],
        },
        {
          value: '/public',
          label: 'public',
          children: [
            {
              value: '/public/assets/',
              label: 'assets',
              children: [{
                value: '/public/assets/style.css',
                label: 'style.css',
              }],
            },
            {
              value: '/public/index.html',
              label: 'index.html',
            },
          ],
        },
        {
          value: '/.env',
          label: '.env',
        },
        {
          value: '/.gitignore',
          label: '.gitignore',
        },
        {
          value: '/README.md',
          label: 'README.md'
        },
      ]),
      editable: [],
      expanded: [
        '/app/Http',
      ]
    }
    this.onExpand = this.onExpand.bind(this);
    this.getExtraNode = this.getExtraNode.bind(this);
    this.onFinishedEdit = this.onFinishedEdit.bind(this);
  }

  static childContextTypes = {

  }

  getChildContext() {
    return {
    }
  }

  onExpand(expanded) {
    this.setState({ expanded });
  }

  addNode(parentNode, newNode) {
    const { nodes, expanded } = this.state;
    const nodePath = this.getNodePathByValue(nodes, parentNode.value);

    this.setState({
      expanded: expanded.concat(parentNode.value),
      nodes: nodes.updateIn(nodePath.concat("children"), List(), children => {
        return children.push(fromJS(newNode))
      }),
      editable: [newNode.value]
    });
  }

  getNodePathByValue(nodes, value) {
    let ret: any[] = null;
    nodes.forEach((node, index) => {
      if (node.get("value") == value) {
        ret = [index];
        return false;
      }
      else if (node.get("children")) {
        const childPath = this.getNodePathByValue(node.get("children"), value);
        if (childPath) {
          ret = [index, "children"].concat(childPath);
          return false;
        }
      }
    })
    return ret;
  }

  getExtraNode(node) {
    if (node.editable) return null;
    if (node.selected || node.hover) {
      const elem = [];
      elem.push(<span key="add" className="button add" onClick={() => {
        const count = this.newCount++;
        this.addNode(node, { value: "new node" + count, label: "new node" + count })
      }} title="add node"></span>)
      return elem;
    }
  }

  onFinishedEdit(node) {
    const { nodes } = this.state;
    const nodePath = this.getNodePathByValue(nodes, node.value);

    this.setState({    
      nodes: nodes.updateIn(nodePath, oldNode => {
        return oldNode.set("label", node.label)
      }),
      editable: []
    });

  }


  render() {
    const { checked, expanded, editable } = this.state;
    return (
      <Tree nodes={this.state.nodes.toJS()}
        onExpand={this.onExpand}
        expanded={expanded}
        editable={editable}
        onFinishedEdit={this.onFinishedEdit}
        getExtraNode={this.getExtraNode}>
      </Tree >
    );
  }
}


$(function () {
  ReactDOM.render(
    <App></App>
    , document.getElementById('content')
  );
})
